<?php
namespace zake\server\ws;

use zake\app\user\User;
use zake\app\wChat\Package;
use zake\foundation\reactor\Reactor;
use zake\foundation\reactor\trigger\connect\WsConnect;
use zake\helper\Console;
use zake\server\zadb\ZaClient;

class WsLogicConnect extends WsConnect implements WsHandler
{


    /**
     * @var null | User
     */
    private $connectUser = null;


    /**
     * 接收到客户端消息,转发用户消息
     * @param $buffer
     *
     * @author liu.bin 2020-05-12 00:16
     */
    public function onBufferHandler($buffer)
    {
        //Console::success("buffer:[{$buffer}]");
        //$this->writeBuffer("---bbb---".$buffer);
    }



    /**
     * 握手成功回调
     *
     * @author liu.bin 2020-05-06 16:47
     */
    public function onConnectHandler($handShakeBuffer)
    {
        // 解析用户
        $path   = $this->_parsePathInfo($handShakeBuffer);
        $token  = substr($path,1);
        $user   = User::getUserByToken($token);


        // 登陆失败
        if(empty($user)){
            $body           = [];
            $body['token']  = $token;
            $package        = Package::create(Package::TYPE_S_LOGIN_FAIL,$this->getSessionId(),$body);
            $this->writeBuffer($package->encode(),function (){
                $this->close();
            });
            return;
        }

        $user->setSessionId($this->getSessionId());
        $this->connectUser = $user;

        // todo 向 master 注册上线信息
        $dbClient = ZaClient::singleton();





        // 获取我的好友
        $friendsMap     = $user->getMyFriend();

        // todo 获取好友的 sessionId
        $sessionList = [];
        foreach ($sessionList as $sessionId){
            $this->writeBufferTo($sessionId,"i am on line");
        }





//        $connectList    = Reactor::getConnectMap();
//        // 通知好友，我上线啦
//        foreach ($connectList as $connect){
//            if( !($connect instanceof WsLogicConnect) || $connect === $this){
//                continue;
//            }
//            $userId = $connect->getConnectUser()->id;
//
//            Console::warnning("userid:[{$userId}]");
//
//            if(isset($friendsMap[$userId])){
//                Console::warnning("我[".$this->connectUser->nickName."]上线啦. 通知[".$friendsMap[$userId]->nickName."]");
//                $body           = [];
//                $body['user']   = $this->connectUser;
//                $package        = Package::create(Package::TYPE_S_FRI_ON,$connect->getSessionId(),$body);
//                $connect->writeBuffer($package->encode());
//                $friendsMap[$userId] = $connect->getConnectUser();
//            }
//        }

        // 响应数据
        $data               = [];
        $data['user']       = $user;
        $data['friends']    = array_values($friendsMap);
        $package            = Package::create(Package::TYPE_S_LOGIN_SUCCESS,$this->getSessionId(),$data);
        $this->writeBuffer($package->encode(),function (){
            Console::success("web socket init success");
        });

    }


    /**
     * 接收pong 操作
     *
     * @author liu.bin 2020-05-12 00:13
     */
    public function onPongHandler()
    {

    }


    /**
     * 断开连接
     *
     * @author liu.bin 2020-05-12 00:15
     */
    public function onCloseHandler()
    {
        $user = $this->connectUser;

        // 获取我的好友
        $friendsMap     = $user->getMyFriend();
        $connectList    = Reactor::getConnectMap();
        // 通知好友，我下线啦
        foreach ($connectList as $connect){
            if($connect !== $this && $connect instanceof WsLogicConnect && !is_null($connect->connectUser)){
                $userId = $connect->connectUser->id;
                if(isset($friendsMap[$userId])){
                    $data           = [];
                    $data['user']   = $this->connectUser;
                    $package        = Package::create(Package::TYPE_S_FRI_OFF,$connect->getSessionId(),$data);
                    $connect->writeBuffer($package->encode());
                }
            }
        }
    }


    /**
     * 获取当前用户
     * @return null|User
     *
     * @author liu.bin 2020-05-12 22:03
     */
    public function getConnectUser()
    {
        return $this->connectUser;
    }


    private function _parsePathInfo($buffer)
    {
        if(strpos($buffer,"\r\n")){

            list($line,) = explode("\r\n",$buffer,2);
            list($method,$path,$httpv) = explode(" ",$line);
            return $path;
        }
        return "no header";
    }

}
